#ifndef __SubMesh_H__
#define __SubMesh_H__

#include "d3dheaders.h"

#include "video/SubMeshRenderGroup.h"
//#include "video/Animation.h"
#include "video/AxisAlignedBox.h"
#include "video/Array.h"
#include <string>
#include <vector>

namespace KEngine
{


class Material;
class Skeleton;
class Device;
class SubMesh
{
	friend class MeshSerializer;
	friend class SubEntity;

public:
	struct VertexData
	{
		D3DXVECTOR3			pos;
	};

	struct FaceData
	{
		int					v[3];
		int					mtl;
	};

	struct TVertexData
	{
		D3DXVECTOR2			tex;
	};

	struct TFaceData
	{
		int					tv[3];
	};

	struct NormalData
	{
		D3DXVECTOR3			fn;
		D3DXVECTOR3			vn[3];
	};

	struct SkinData
	{
		struct BoneWeightData
		{
			float			weight;
			std::string		boneName;
			int				boneID;		// not assigned until mesh linked to a skeleton
		};

		Array<BoneWeightData> bones[3];
	};

	typedef std::vector<SubMeshRenderGroup*> SubMeshRenderGroupList;

public:
	SubMesh(Device* device);
	~SubMesh();

	void optimize();

	void setMtl(Material* mtl);
	void attachSkeleton(Skeleton* skeleton);
	void dettachSkeleton();

	const std::string& getName() const;
	bool hasSkeleton();

	void buildBounds();
	const AxisAlignedBox& getBounds() const;

protected:
	// rough data
	D3DXMATRIX					mInitTM;
	std::string					mName;
	std::string					mParentName;

	Array<VertexData>		mVertexData;
	Array<FaceData>			mFaceData;
	Array<TVertexData>		mTVertexData;
	Array<TFaceData>		mTFaceData;
	Array<NormalData>		mNormalData;
	Array<SkinData>			mSkinData;

	// optimized data
	Material*				mMaterial;
	SubMeshRenderGroupList	mRenderGroups;
	Skeleton*				mSkeleton;
	AxisAlignedBox			mAABB;

	Device*					mDevice;
};

typedef std::vector<SubMesh*> SubMeshList;
typedef std::vector<SubMesh*>::iterator SubMeshIterator;

}

#endif //